package com.liyao.windowtest4.controller.wrench;

import com.liyao.windowtest4.Utils.SharedModel;
import com.liyao.windowtest4.Utils.SocketClientUtil;
import com.liyao.windowtest4.pojo.Routine;
import com.liyao.windowtest4.pojo.torqueRow;
import com.liyao.windowtest4.pojo.wrenchRow;
import javafx.animation.PauseTransition;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.util.StringConverter;
import javafx.util.converter.NumberStringConverter;
import net.sf.json.JSONObject;

import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.liyao.windowtest4.Utils.NetworkInfoExtractor.NetworkInfoExtractor;
import static com.liyao.windowtest4.Utils.getWiFiName.getWiFiName;

/**
 * @program: windowtest4
 * @description:
 * @author: liu yan
 * @create: 2024-10-30 11:02
 */
public class createWrenchController implements Initializable {
    @FXML
    public TextField SNText;
    public TextField torqueMinText;
    public TextField ipAddressText;
    public TextField torqueMaxText;
    public TextField portText;
    public TextField SSIDText;
    public TextField SubnetMaskTest;
    public TextField passwordText;
    public TextField gatewayText;
//    public TextField oldPortText;
//    public TextField oldIpAddressText;
    public Label localIp;

    private boolean isAdd=false;
    private String IPTest;
    private String WGTest;

    public boolean isAdd() {
        return isAdd;
    }

    private Service<Void> service;

    private SocketClientUtil clientUtil;

    private String configDirPath = System.getProperty("user.dir") + File.separator + "config" + File.separator;


    public void createWrenchSubmit(ActionEvent actionEvent) {

        JSONObject js=new JSONObject();
        boolean isValid = true;
        isValid &= !isTextFieldEmptyOrWhitespace(SNText, "请填写扳手SN码");
        isValid &= !isTextFieldEmptyOrWhitespace(torqueMinText, "请填写扳手的最小扭矩");
        isValid &= !isTextFieldEmptyOrWhitespace(torqueMaxText, "请填写扳手的最大扭矩");
        isValid &= !isTextFieldEmptyOrWhitespace(SSIDText, "请填写Wi-Fi名称");
        isValid &= !isTextFieldEmptyOrWhitespace(passwordText, "请填写Wi-Fi密码");
        isValid &= !isTextFieldEmptyOrWhitespace(ipAddressText, "请填写扳手的IP地址");
        isValid &= !isTextFieldEmptyOrWhitespace(portText, "请填写扳手的端口号");
        isValid &= !isTextFieldEmptyOrWhitespace(SubnetMaskTest, "请填写子网掩码");
        isValid &= !isTextFieldEmptyOrWhitespace(gatewayText, "请填写网关");
//        isValid &= !isTextFieldEmptyOrWhitespace(oldIpAddressText, "请填写原IP地址");
//        isValid &= !isTextFieldEmptyOrWhitespace(oldPortText, "请填写原端口号");

        if (isValid) {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            js.put("SN",SNText.getText());
            js.put("TorqueName",SNText.getText());
            js.put("TorqueMin",Double.parseDouble(torqueMinText.getText()));
            js.put("TorqueMax",Double.parseDouble(torqueMaxText.getText()));
            js.put("SSID",SSIDText.getText());
            js.put("password",passwordText.getText());
            js.put("Host",ipAddressText.getText());
            js.put("Port",Integer.parseInt(portText.getText()));
            js.put("SubnetMask",SubnetMaskTest.getText());
            js.put("gateway",gatewayText.getText());
            js.put("addTime",sdf.format(new Date()));

            // 定义文件路径
            String filePath = configDirPath+"torqueItems.txt"; // 文件路径

            try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) { // true 表示追加模式
                // 遍历数据列表并写入文件
                writer.write(js.toString()); // 假设DataRow有一个合适的toString()方法，该方法返回包含所有字段的字符串表示
                writer.newLine(); // 每行数据后换行
                isAdd=true;
//                showAlert(Alert.AlertType.INFORMATION,"添加成功",null,"扳手添加成功");

                Stage stage = (Stage) ((Button) actionEvent.getSource()).getScene().getWindow();
                stage.close();
            } catch (IOException e) {
                e.printStackTrace(); // 打印错误堆栈信息到控制台（通常不推荐在生产环境中这样做）
                // 在实际应用中，您应该使用更用户友好的错误处理方式，比如显示一个错误消息对话框
                isAdd=false;
            }

            //下发给扳手IP地址和端口
//            this.service = new Service<>() {
//                // 添加一个取消标志
//                private volatile boolean cancelled = false;
//                //            private volatile boolean isAdd1 = false;
//                @Override
//                protected Task<Void> createTask() {
//                    return new Task<Void>() {
//                        @Override
//                        protected Void call() throws Exception {
//
//                            int maxRetries = 5;
//                            int retryCount = 0;
//
//                            while (!cancelled && retryCount < maxRetries) {
//                                updateMessage("正在添加扳手");
////                                updateMessage("正在第" + (retryCount + 1) + "次连接扳手配置网络");
////                                clientUtil = new SocketClientUtil(oldIpAddressText.getText(), Integer.parseInt(oldPortText.getText()));
//                                try{
//                                    // 建立连接
////                                    clientUtil.connect();
////
////                                    String mess="RSWS;01;"+SNText.getText()+";01;"+SSIDText.getText()+";"+passwordText.getText()+";"+ipAddressText.getText()+";"+SubnetMaskTest.getText()+";"+gatewayText.getText()+";"+portText.getText()+";;\r\n";
////                                    // 发送消息到服务器
////                                    clientUtil.sendMessage("RSWS;01;"+SNText.getText()+";01;"+SSIDText.getText()+";"+passwordText.getText()+";"+ipAddressText.getText()+";"+SubnetMaskTest.getText()+";"+gatewayText.getText()+";"+portText.getText()+";;\r\n");
////                                    // 从服务器接收消息
////                                    String response = clientUtil.receiveMessage();
////                                    System.out.println("Server response 网络：: " + response);
//
//                                    // 连接成功
//                                    updateMessage("添加成功");
//
//                                    //把扳手信息插入文档中
//                                    WriteTxt(SNText.getText(),torqueMinText.getText(),torqueMaxText.getText(),SSIDText.getText(),passwordText.getText(),ipAddressText.getText(),portText.getText(),SubnetMaskTest.getText(),gatewayText.getText());
//
////                                    clientUtil.close();
//                                    cancelled=true;
//
//                                    break;
//
//                                } catch (IOException ex) {
//                                    retryCount++;
//                                    if (retryCount >= maxRetries) {
//                                        updateMessage("连接失败，已达到最大重试次数");
//                                    }
//
//                                    // 模拟延迟
//                                    Thread.sleep(1000);
//                                }
//                            }
//                            if (isCancelled()) {
//                                updateMessage("任务已取消");
//                            }
//                            return null;
//                        }
//                        @Override
//                        protected void cancelled() {
//                            super.cancelled();
//                            // 当任务被取消时，设置取消标志（这通常会在调用service.cancel()时自动发生）
//                            cancelled = true;
//                            // 您可能还需要在这里添加额外的清理逻辑，比如关闭已经打开的Socket等
//                        }
//                    };
//                }
//            };
//            Dialog<Void> dialog = createDialog("正在连接扳手配置网络...");
////        service.setOnSucceeded(event -> dialog.close());
//            service.setOnSucceeded(event -> {
//                isAdd=true;
//                Stage stage = (Stage) ((Button) actionEvent.getSource()).getScene().getWindow();
//                stage.close();
//                PauseTransition delay = new PauseTransition(Duration.seconds(3)); // 延迟3秒
//                delay.setOnFinished(event2 -> dialog.close()); // 延迟结束后关闭对话框
//                delay.play();
//            });
//            // 在对话框关闭时取消服务
//            dialog.setOnCloseRequest(event -> {
//                isAdd=false;
//                if (service.isRunning()) {
//                    service.cancel();
//                    try {
//                        clientUtil.close();
//                    } catch (IOException e) {
//                        throw new RuntimeException(e);
//                    }
//                }
//                dialog.close(); // 这行通常不需要，因为对话框已经在关闭请求中了
//            });
//
//            service.start();
//
//            dialog.showAndWait();

            System.out.println("我提交了");
        }
    }

    private void showAlert(Alert.AlertType alertType, String title, String headerText,String ContentText) {
        Alert alert = new Alert(alertType);
        alert.setTitle(title);
        alert.setHeaderText(headerText);
        alert.setContentText(ContentText); // 可以根据需要自定义内容文本
        alert.showAndWait(); // 显示对话框并等待用户响应
    }

    private void setNumericTextFormatter(TextField textField) {
        StringConverter<Number> converter = new NumberStringConverter();
        textField.setTextFormatter(new TextFormatter<>(converter, 0, (change) -> {
            if (change.isContentChange()) {
                String text = change.getControlNewText();
                if (text.matches("-?\\d+(\\.\\d*)?|(\\.?)$")) {
                    return change;
                }
            }
            return null; // 拒绝不符合格式的更改
        }));
    }
//{"SN":"CGHZ0710001","TorqueName":"CGHZ0710001","TorqueMin":1,"TorqueMax":10,"SSID":"BYD-006","password":"87834466","Host":"192.168.110.54","Port":"4545","SubnetMask":"255.255.255.0","gateway":"192.168.110.1","addTime":"2024-11-21 14:42:44"}
    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        setNumericTextFormatter(torqueMinText);
        setNumericTextFormatter(torqueMaxText);
        portText.setText("4545");
        SSIDText.setText(getWiFiName());
        RecommendedIP();
//        Map<String,String> netMap=NetworkInfoExtractor();
//        if(netMap!=null){
//            localIp.setText(netMap.get("ipv4Address"));
//            SubnetMaskTest.setText(netMap.get("SubnetMask"));
//            this.IPTest=netMap.get("ipv4Address");
//            this.WGTest=netMap.get("DefaultGateway");
//            gatewayText.setText(netMap.get("DefaultGateway"));
//            ipAddressText.setText(RecommendedIP());
//        }
    }

    private void RecommendedIP(){
        String filePath = configDirPath+"torqueItems.txt"; // 文件路径

        Map<String,String> netMap=NetworkInfoExtractor();
        if(netMap!=null){
            localIp.setText(netMap.get("ipv4Address"));
            SubnetMaskTest.setText(netMap.get("SubnetMask"));
            this.IPTest=netMap.get("ipv4Address");
            this.WGTest=netMap.get("DefaultGateway");
            gatewayText.setText(netMap.get("DefaultGateway"));

            List<String> lines = new ArrayList<>();
            try (InputStream inputStream = new FileInputStream(filePath);
                 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                String line;
                while ((line = reader.readLine())!= null) {
                    JSONObject js=JSONObject.fromObject(line);
                    lines.add(js.get("Host").toString());
                }

                lines.add(this.WGTest);
                lines.add(this.IPTest);
                Random random = new Random();
                String fixedPrefix = this.IPTest.substring(0,this.IPTest.lastIndexOf("."));
                String newIP;
                do {
                    int lastOctet = random.nextInt(256);
                    newIP = fixedPrefix +"."+ lastOctet;
                } while (lines.contains(newIP));
                ipAddressText.setText(newIP);
            } catch (IOException e) {
                System.err.println("读取文件错误："+e);
            }
        }
    }

    private boolean isTextFieldEmptyOrWhitespace(TextField textField, String errorMessage) {
        String text = textField.getText().trim();
        if (text.isEmpty()) {
            showAlert(Alert.AlertType.ERROR,"验证错误", "请填写所有必填项",errorMessage);
            System.err.println(errorMessage);
            return true;
        }
        return false;
    }

    public wrenchRow getNewData() {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        wrenchRow newData = new wrenchRow(SNText.getText(),
                SNText.getText(),
                Double.parseDouble(torqueMinText.getText()),
                Double.parseDouble(torqueMaxText.getText()),
                SSIDText.getText(),
                passwordText.getText(),
                ipAddressText.getText(),
                Integer.parseInt(portText.getText()),
                SubnetMaskTest.getText(),
                gatewayText.getText(),
                sdf.format(new Date()));
        return newData;
    }

    private Dialog<Void> createDialog(String title) {
        Dialog<Void> dialog = new Dialog<>();
        dialog.setTitle(title);
        dialog.setHeaderText(null);
        dialog.setGraphic(null);

        // 创建一个带有首选尺寸的Label
        Label label = new Label();
        label.setPrefWidth(400); // 设置首选宽度，可以根据需要调整
        label.setWrapText(true); // 启用文本换行
        dialog.getDialogPane().setContent(label);

        dialog.getDialogPane().getButtonTypes().addAll(ButtonType.CLOSE);

        // 更新标签内容
        service.messageProperty().addListener((obs, oldMessage, newMessage) -> {
            Platform.runLater(() -> label.setText(newMessage));
        });

        // 尝试调整对话框的初始尺寸（这不是标准方法，但可能有助于在某些情况下改善显示效果）
        // 注意：这种方法的效果可能因JavaFX版本和平台而异
        dialog.getDialogPane().prefWidthProperty().bind(label.prefWidthProperty());
        dialog.getDialogPane().prefHeightProperty().bind(label.prefHeightProperty().add(50)); // 额外的高度用于按钮等

        // 由于prefHeight的绑定可能不够准确（因为还包括了按钮和其他元素），您可能需要手动设置一个更大的值
        // 或者，您可以在对话框显示后使用反射或其他技巧来调整其尺寸（这通常不推荐，因为它依赖于内部实现）

        // 一个更好的方法是使用Stage并完全自定义对话框的外观和尺寸
        // 但这将需要更多的工作，并且会失去Dialog类提供的一些便利功能

        return dialog;
    }

    private void WriteTxt(String SN,String TorqueMin,String TorqueMax,String SSIDText,String passwordText,String ipAddressText,String portText,String SubnetMaskTest,String gatewayText) throws IOException {
        String filePath=configDirPath+"torqueItems.txt";
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 定义要写入的文件路径
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
            JSONObject json=new JSONObject();
            json.put("SN",SN);
            json.put("TorqueName",SN);
            json.put("TorqueMin",TorqueMin);
            json.put("TorqueMax",TorqueMax);
            json.put("SSID",SSIDText);
            json.put("password",passwordText);
            json.put("Host",ipAddressText);
            json.put("Port",portText);
            json.put("SubnetMask",SubnetMaskTest);
            json.put("gateway",gatewayText);
            json.put("addTime",sdf.format(new Date()));
            // 写入文件
            writer.write(json.toString());
            writer.newLine();
            System.out.println("写入torqueItems文件成功,write ok!");
            this.isAdd=true;
        } catch (IOException e) {
            e.printStackTrace(); // 打印错误堆栈信息到控制台（通常不推荐在生产环境中这样做）
            // 在实际应用中，您应该使用更用户友好的错误处理方式，比如显示一个错误消息对话框
            this.isAdd=false;
        }

    }
}
